package fr.bugtracker.commun.outils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;

import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import org.primefaces.context.RequestContext;

import fr.bugtracker.bean.session.BeanApplication;
import fr.bugtracker.bean.session.BeanSession;

/**
 * @author Laurent
 * @version 0.1
 */
public abstract class UtilsJsf {

	/**
	 * Constructeur de la classe <code>UtilsJsf</code>.
	 */
	public UtilsJsf() {
	}

	/**
	 * Retourne le bean typé
	 * @param pElExpression {@link String}
	 * @param pType {@link Class}< T >
	 * @return < T >
	 */
	public static <T> T getBean(String pElExpression, Class<T> pType) {
		FacesContext vContext = FacesContext.getCurrentInstance();
		return vContext.getApplication().evaluateExpressionGet(vContext, "#{" + pElExpression + "}", pType);
	}

	/**
	 * Retourne le bean application
	 * @return {@link BeanApplication}
	 */
	public static BeanApplication getBeanApplication() {
		return getBean("beanApplication", BeanApplication.class);
	}

	/**
	 * Retourne le bean session
	 * @return {@link BeanSession}
	 */
	public static BeanSession getBeanSession() {
		return getBean("beanSession", BeanSession.class);
	}

	/**
	 * Ajoute un message dans le facescontext à partir du fichier properties coté metier de l'application
	 * @param pSeverity {@link Severity}
	 * @param pMessage {@link String}
	 * @param pProperties {@link String}...
	 */
	public static void addMessage(Severity pSeverity, String pMessage, String... pProperties) {
		String vMessage = UtilsMetier.getMessage(pMessage, pProperties);
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(pSeverity, vMessage, vMessage));
	}

	/**
	 * Execute une fonction javascript
	 * @param pJavascript {@link String}
	 */
	public static void executeJavascript(String pJavascript) {
		RequestContext context = RequestContext.getCurrentInstance();
		context.execute(pJavascript);
	}

	/**
	 * Envoi une requête ajax pour raffraichir plusieurs composants
	 * @param pUpdate {@link String}...
	 */
	public static void executeUpdate(String... pUpdate) {
		RequestContext context = RequestContext.getCurrentInstance();
		context.update(Arrays.asList(pUpdate));
	}

	/**
	 * @param fc {@link FacesContext}
	 * @param redirectPage {@link String}
	 * @throws FacesException -
	 */
	public static void doRedirect(FacesContext fc, String redirectPage) {
		ExternalContext ec = fc.getExternalContext();
		try {
			if (ec.isResponseCommitted()) {
				return;
			}
			ec.redirect(ec.getRequestContextPath() + (redirectPage != null ? redirectPage : ""));
		} catch (IOException e) {
			throw new FacesException(e);
		}
	}

	/**
	 * Gestion des exceptions systemes
	 * @param pException {@link Throwable}
	 */
	public static void gestionExceptionSysteme(Throwable pException) {
		UtilsLogger.logException(pException);
		String vDate = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(Calendar.getInstance().getTime());
		if (UtilsAuthentication.getUtilisateurSession() != null) {
			FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("application-erreur", String.format("%s - [%s] %s", vDate, pException.getClass().getSimpleName(), pException.getMessage()));
			doRedirect(FacesContext.getCurrentInstance(), "/faces/pages/public/errors/erreur-generale.xhtml");
		} else {
			pException.printStackTrace();
		}
	}

	/**
	 * change le timeout de la session
	 * @param sessionTimeout int
	 */
	public static void changeSessionTimeout(int sessionTimeout) {
		((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().setMaxInactiveInterval(sessionTimeout);
	}

}
